package com.starbugs.wehcat.data;

import com.starbugs.wehcat.pojo.Ingredient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.sql.ResultSet;
import java.sql.SQLException;

// Spring定义了一系列的构造型（stereotype）注解， dao层使用@repository注解
// 其他注解还包括@Controller和@Component

/**
 * @author starbooks
 */
@Repository
public class JdbcIngredientRepository implements IngredientRepository {

  // 当Spring创建JdbcIngredientRepository bean的时候，
  // 它会通过@Autowired标注的构造器将JdbcTemplate注入进来。
  // 这个构造器将JdbcTemplate赋值给一个实例变量，
  // 这个变量会被其他方法用来执行数据库查询和插入操作

  @Autowired
  public JdbcIngredientRepository(JdbcTemplate jdbc) {
    this.jdbc = jdbc;
  }

  private JdbcTemplate jdbc;

  // JdbcTemplate的query()方法会接受要执行的SQL
  // 以及SpringRowMapper的一个实现（用来将结果集中的每行数据映射为一个对象
  // queryForObject()方法的运行方式和query()非常类似，只不过它只返回一个对象，而不是对象的List

  @Override
  public Iterable<Ingredient> findAll() {
    return jdbc.query("select id, name, type from Ingredient",
        this::mapRowToIngredient);
  }

  @Override
  public Ingredient findOne(String id) {
    return jdbc.queryForObject("select id, name, type from Ingredient where id = ? ",
        this::mapRowToIngredient, id);
  }

  @Override
  public Ingredient save(Ingredient ingredient) {
    jdbc.update(
        "insert into Ingredient (id, name, type) values (?, ?, ?)",
        ingredient.getId(),
        ingredient.getName(),
        ingredient.getType().toString()
    );
    return ingredient;
  }

  // findAll()和findOne()中的RowMapper参数都是通过对mapRowToIngredient()的方法引用指定的

  private Ingredient mapRowToIngredient(ResultSet rs, int rowNum) throws SQLException {
    return new Ingredient(
        rs.getString("id"),
        rs.getString("name"),
        Ingredient.Type.valueOf(rs.getString("type"))
    );
  }
}
